package priv.pront.code.mati.national.practice;

import java.util.*;

/**
 * @Author: Pronting
 * @Description:
 * @DateTime: 2023/12/1 13:54
 **/
public class P1825_Corn_Maze_S {

    static int n, m;
    static char[][] g;
    static int[][][] position = new int[26][2][2];
    static Set<Character> containsSet = new HashSet<>();
    static Queue<int[]> queue = new LinkedList<>();
    static int[] dx = new int[]{-1, 1, 0, 0}, dy = new int[]{0, 0, -1, 1};
    static boolean[][] st;
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        m = scanner.nextInt();
        g = new char[n][m];
        st = new boolean[n][m];
        int startX = -1, startY = -1;
        for (int i = 0; i < n; i++) g[i] = scanner.next().toCharArray();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (g[i][j] >= 'A' && g[i][j] <= 'Z') {
                    if(!containsSet.contains(g[i][j])){
                        position[g[i][j] - 'A'][0][0] = i;
                        position[g[i][j] - 'A'][0][1] = j;
                    }else{
                        position[g[i][j] - 'A'][1][0] = i;
                        position[g[i][j] - 'A'][1][1] = j;
                    }
                    containsSet.add(g[i][j]);
                }
                if(g[i][j] == '@'){
                    startX = i;
                    startY = j;
                }
            }
        }
        st[startX][startY] = true;
        queue.add(new int[]{startX, startY, 0});
        while (!queue.isEmpty()) {
            int[] poll = queue.poll();
            if(g[poll[0]][poll[1]] == '='){
                System.out.println(poll[2]);
                return;
            }
            char cur = g[poll[0]][poll[1]];
            if (containsSet.contains(cur)) {
                int[] ans = jump(poll[0], poll[1]);
                poll[0] = ans[0];
                poll[1] = ans[1];
            }
            for (int i = 0; i < 4; i++) {
                int nx = dx[i] + poll[0];
                int ny = dy[i]  + poll[1];
                if (nx < 0 || nx >= n || ny < 0 || ny >= m || st[nx][ny] || g[nx][ny] == '#') continue;
                st[nx][ny] = true;
                queue.add(new int[]{nx, ny, poll[2] + 1});
            }
        }
    }

    private static int[] jump(int row, int col){
        char cur = g[row][col];
        int jumpX , jumpY;
        if (position[cur - 'A'][0][0] == row && position[cur - 'A'][0][1] == col) {
            jumpX = position[cur - 'A'][1][0];
            jumpY = position[cur - 'A'][1][1];
        } else {
            jumpX = position[cur - 'A'][0][0];
            jumpY = position[cur - 'A'][0][1];
        }
        return new int[]{jumpX, jumpY};
    }
}
